package com.simple.datax.service;

import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.rpc.RpcException;
import com.simple.datax.SimpleFailMessage;
import com.simple.datax.SimpleMessage;
import com.simple.datax.SimpleObject;
import com.simple.datax.api.MessageProcessor;
import com.simple.datax.api.NeedResendSimpleException;
import com.simple.datax.api.SimpleException;
import com.simple.datax.utils.MessageUtils;
import com.simple.datax.utils.SimpleConstants;

/**
 * @Title: AbstractMessageProcessor.java
 * @Package com.simple.datax.service
 * @Description: 消息处理抽象类,（只用于消息处理流程中的类）
 * @author Paladin Chen
 * @date 2012-12-24 下午1:35:46
 * @version V1.0
 */
public abstract class AbstractMessageProcessor implements MessageProcessor {

	private static final Logger logger = LoggerFactory.getLogger(AbstractMessageProcessor.class);
	//protected Logger logger = LoggerFactory.getLogger(getClass());

	private List<MessageProcessor> nextProcessors;

	private List<MessageProcessor> backupServices;

	private MessageProcessor failService;

	private MessageProcessor statusService;

	private DBSystemLogService dbLogService;

	private ResponseMessageService responseService;

	private boolean mustResponse = true;

	private short errorType = SimpleConstants.ERROR_TYPE_UNKOWN;

	private short errorLevel = SimpleConstants.ERROR_LEVEL_NORMAL;

	private int responseCode = SimpleConstants.RESPONSE_CODE_UNKNOWN;

	private String responseMsg = SimpleConstants.RESPONSE_MSG_UNKNOWN;

	/**
	 * 需要具体类实现的方法
	 * 
	 * @param src
	 * @throws SimpleException
	 */
	public abstract void realProcess(SimpleMessage src) throws SimpleException;

	/**
	 * 用来设置出错时需要使用的信息
	 */
	public void setErrorInfos(short errorType, short errorLevel, int responseCode, String responseMsg) {
		this.errorType = errorType;
		this.errorLevel = errorLevel;
		this.responseCode = responseCode;
		this.responseMsg = responseMsg;
	}

	/**
	 * 根据设定的格式解析出主要的格式，
	 * 因为目前对于加压报文，格式可能是zip.xml,或gzip.xml,主要的格式还是xml，只不过其中的内容是压缩过的。
	 * 
	 * @param format
	 * @return
	 */
	public String getMainFormat(String format) {
		if (StringUtils.isBlank(format)) {
			return null;
		} else {
			if (format.indexOf(".") > 0) {
				return format.substring(format.indexOf(".") + 1);
			} else {
				return format;
			}
		}
	}

	public String getSubFormat(String format) {
		if (StringUtils.isBlank(format)) {
			return null;
		} else {
			if (format.indexOf(".") > 0) {
				return format.substring(0, format.indexOf("."));
			} else {
				return null;
			}
		}
	}

	/**
	 * 实现公共的process
	 */
	@Override
	public void process(SimpleObject src) throws SimpleException {
		if(src == null){
			logger.info("######## SimpleMessage is null.");
			logger.error("SimpleObject is null.");
			return;
		}
		
		//logger.debug("Teste Logeger");
		
		if (src instanceof SimpleMessage) {
			try {
				realProcess((SimpleMessage) src);

				// 放入到realProcess中处理
				// callNextStep(src);
			} catch (RpcException de) {
				// dubbo 调用失败
				logger.warn(((SimpleMessage) src).toLog() + "Rpc Error:", de);
			} catch (NeedResendSimpleException de) {
				//处理过程抛出的需要重发异常
				logger.warn(((SimpleMessage) src).toLog() + "Need Resend Error:", de);
			} catch (Exception e) {
				String errorinfo = e.getMessage();
				logger.error(((SimpleMessage) src).toLog(), e);

				try {
					// 异常处理
					SimpleFailMessage sfm = MessageUtils.castFailMessage(errorinfo, errorType, errorLevel,
							(SimpleMessage) src);

					this.callFailService(sfm);// 注意这里需要处理SimpleFailMessage
				} catch (Exception e3) {
					logger.error(((SimpleMessage) src).toLog() + "Proc FailMessage Error:", e3);
				}

				try {
					// 处理错误response报文
					this.callResponseService((SimpleMessage) src, responseCode, responseMsg, isMustResponse());
				} catch (Exception e3) {
					logger.error(((SimpleMessage) src).toLog() + "Proc FailMessage Response Error:", e3);
				}
			}
		} else {
			logger.error("The Paramter MUST be SimpleMessage!");
		}
	}

	/**
	 * 用来发送回执信息
	 * 
	 * @param src
	 * @param responseCode
	 * @param responseMsg
	 * @param isMust
	 */
	public void callResponseService(SimpleMessage src, int responseCode, String responseMsg, boolean isMust) {
		if (responseService == null) {
			logger.info("There is no responseMessage Service!");
		} else {
			try {
				responseService.response(src, responseCode, responseMsg, isMust);
			} catch (Exception e) {
				logger.error(src.toLog() + "Send Response message Error:", e);
			}
		}
	}

	/**
	 * 默认根据报文内容发送回执
	 * 
	 * @param src
	 * @param responseCode
	 * @param responseMsg
	 */
	public void callResponseService(SimpleMessage src, int responseCode, String responseMsg) {
		this.callResponseService(src, responseCode, responseMsg, false);
	}

	/**
	 * 记数据库日志
	 * 
	 * @param logThread
	 * @param actionName
	 * @param logLevel
	 * @param logContent
	 */
	public void callDbLogService(String logThread, String actionName, String logLevel, String logContent) {
		if (dbLogService != null) {
			dbLogService.insertLog(logThread, actionName, logLevel, logContent);
		} else {
			logger.info("There is no dbLog Service!!!!");
		}
	}

	/**
	 * 变更报文处理状态
	 * 
	 * @param src
	 */
	public void callStatusService(SimpleObject src) {
		if (!(src instanceof SimpleMessage)) {
			logger.error("The Paramter MUST be SimpleMessage!");
			return;
		}

		if (statusService != null) {
			try {
				statusService.process(src);
			} catch (Exception e) {
				logger.error(((SimpleMessage) src).toLog() + "Error Occur When Call "
						+ statusService.getClass().getName(), e);
			}
		}
	}

	/**
	 * 在数据库中记载处理失败信息
	 * 
	 * @param src
	 */
	public void callFailService(SimpleObject src) {
		if (!(src instanceof SimpleFailMessage)) {
			logger.error("The Paramter MUST be SimpleFailMessage!");
			return;
		}

		if (failService != null) {
			try {
				failService.process(src);
			} catch (Exception e) {
				logger.error(((SimpleFailMessage) src).toLog() + "Error Occur When Call "
						+ failService.getClass().getName(), e);
			}
		} else {
			logger.info("There is no Fail proc Service!!!!");
		}
	}

	/**
	 * 做备份处理，list中可配置文件备份和数据库备份
	 * 
	 * @param src
	 */
	public void callBackupService(SimpleObject src) {
		if (backupServices == null || backupServices.size() < 1) {
			logger.info("There are no backup Services!!!!");
			return;
		}

		if (!(src instanceof SimpleMessage)) {
			logger.error("The Paramter MUST be SimpleMessage!");
			return;
		}

		for (MessageProcessor mp : backupServices) {
			if (mp != null) {
				try {
					mp.process(src);
				} catch (Exception e) {
					logger.error(((SimpleMessage) src).toLog() + "Error Occur When Call " + mp.getClass().getName(), e);
				}
			}
		}
	}

	/**
	 * 调用下一步处理
	 * 
	 * @param src
	 */
	public void callNextStep(SimpleObject src) {
		if (nextProcessors == null || nextProcessors.size() < 1) {
			logger.info("There are no next Processors!!!!");
			return;
		}

		if (!(src instanceof SimpleMessage)) {
			logger.error("The Paramter MUST be SimpleMessage!");
			return;
		}

		int i = 0;
		for (MessageProcessor mp : nextProcessors) {
			if (mp != null) {
				i++;
				try {
					mp.process(src);
				} catch (Exception e) {
					logger.error(((SimpleMessage) src).toLog() + "Error Occur When Call " + mp.getClass().getName(), e);
				}
			}
		}

		if (i == 0) {
			logger.info("The next Processors ARE NULL!!!!");
		}
	}

	public ResponseMessageService getResponseService() {
		return responseService;
	}

	public void setResponseService(ResponseMessageService responseService) {
		this.responseService = responseService;
	}

	public List<MessageProcessor> getNextProcessors() {
		return nextProcessors;
	}

	public void setNextProcessors(List<MessageProcessor> nextProcessors) {
		this.nextProcessors = nextProcessors;
	}

	public List<MessageProcessor> getBackupServices() {
		return backupServices;
	}

	public void setBackupServices(List<MessageProcessor> backupServices) {
		this.backupServices = backupServices;
	}

	public MessageProcessor getFailService() {
		return failService;
	}

	public void setFailService(MessageProcessor failService) {
		this.failService = failService;
	}

	public MessageProcessor getStatusService() {
		return statusService;
	}

	public void setStatusService(MessageProcessor statusService) {
		this.statusService = statusService;
	}

	public DBSystemLogService getDbLogService() {
		return dbLogService;
	}

	public void setDbLogService(DBSystemLogService dbLogService) {
		this.dbLogService = dbLogService;
	}

	/**
	 * 是否必须要回复，如果true，则会回复，如果false，而报文头中要求回复，也会回复。
	 * 
	 * @return
	 */
	public boolean isMustResponse() {
		return mustResponse;
	}

	public void setMustResponse(boolean mustResponse) {
		this.mustResponse = mustResponse;
	}

}
